package com.tjvib.view.activity;

import android.graphics.Bitmap;
import android.graphics.Color;
import android.os.AsyncTask;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.RadioButton;
import android.widget.Spinner;
import android.widget.SpinnerAdapter;
import android.widget.TextView;

import com.jjoe64.graphview.GraphView;
import com.jjoe64.graphview.series.DataPoint;
import com.jjoe64.graphview.series.LineGraphSeries;
import com.tjvib.Constants;
import com.tjvib.R;
import com.tjvib.base.BaseActivity;
import com.tjvib.bean.ResBean;
import com.tjvib.common.LoadingCallback;
import com.tjvib.presenter.BasePresenter;
import com.tjvib.util.LogUtil;
import com.tjvib.util.Manager.DataSetManager;
import com.tjvib.util.Manager.UserManager;
import com.tjvib.util.PoiUtil;
import com.tjvib.util.ToastUtil;
import com.tjvib.view.dialog.LoadingDialog;
import com.tjvib.widget.TitleLayout;

import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class FreqDampingActivity extends BaseActivity implements LoadingCallback {

    private Button freq_btn_confir, freq_btn_export;
    private TextView freq_tv_hz, freq_tv_znb;
    private EditText freq_et_gd;
    private GraphView freq_gv_data;
    private Spinner freq_sp_sensor;
    private RadioButton freq_rb_accx, freq_rb_accy, freq_rb_accz, freq_rb_gj, freq_rb_gang, freq_rb_qt;
    private TitleLayout freq_tit;
    private static LoadingDialog loadingDialog = null;

    private DataSetManager dataSetManager = DataSetManager.getInstance();
    private LineGraphSeries<DataPoint> mSeries1 = new LineGraphSeries<>();

    private String sensorSelect = "", curStru = "";
    private ExecutorService executorService = Executors.newFixedThreadPool(10);
    private int curAxis = 0;
    private long lastClickTime = 0;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Override
    protected int initLayout() {
        return R.layout.activity_freq_damping;
    }

    @Override
    protected boolean initView() {
        freq_tit = findViewById(R.id.freq_tit);
        freq_tit.setTitle(getIntent().getStringExtra("METHOD"));

        freq_btn_export = findViewById(R.id.freq_btn_export);
        freq_btn_export.setOnClickListener(v-> {
            FileReadWriteTask fileReadWriteTask = new FileReadWriteTask();
            fileReadWriteTask.execute();
        });

        freq_gv_data = findViewById(R.id.freq_gv_data);

        freq_sp_sensor = findViewById(R.id.freq_sp_sensor);

        freq_rb_accx = findViewById(R.id.freq_rb_accx);
        freq_rb_accy = findViewById(R.id.freq_rb_accy);
        freq_rb_accz = findViewById(R.id.freq_rb_accz);
        freq_rb_accx.setOnCheckedChangeListener((compoundButton, b) -> {
            if (b) curAxis = 0;
        });
        freq_rb_accy.setOnCheckedChangeListener((compoundButton, b) -> {
            if (b) curAxis = 1;
        });
        freq_rb_accz.setOnCheckedChangeListener((compoundButton, b) -> {
            if (b) curAxis = 2;
        });

        freq_rb_gj = findViewById(R.id.freq_rb_gj);
        freq_rb_gang = findViewById(R.id.freq_rb_gang);
        freq_rb_qt = findViewById(R.id.freq_rb_qt);
        freq_rb_gj.setOnCheckedChangeListener((compoundButton, b) -> {
            if (b) curStru = "钢筋混凝土结构";
        });
        freq_rb_gang.setOnCheckedChangeListener((compoundButton, b) -> {
            if (b) curStru = "钢结构";
        });
        freq_rb_qt.setOnCheckedChangeListener((compoundButton, b) -> {
            if (b) curStru = "砌体结构";
        });

        freq_tv_hz = findViewById(R.id.freq_tv_hz);
        freq_tv_znb = findViewById(R.id.freq_tv_znb);
        freq_btn_confir = findViewById(R.id.freq_btn_confir);
        freq_btn_confir.setOnClickListener(v-> {
            long currentTime = System.currentTimeMillis();
            if (currentTime - lastClickTime < 10000) {
                ToastUtil.show("10秒内请不要重复点击");
            } else {
                lastClickTime = currentTime;
                showResult();
            }
        });

        freq_et_gd = findViewById(R.id.freq_et_gd);
        freq_et_gd.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
            }

            @Override
            public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
            }

            @Override
            public void afterTextChanged(Editable editable) {
                if(!freq_et_gd.getText().toString().isEmpty())
                    freq_btn_confir.setBackground(getResources().getDrawable(R.drawable.selector_purple_rad40));
            }
        });

        return true;
    }

    @Override
    protected boolean initData() {
        List<String> sensorList = dataSetManager.getSensorList();
        SpinnerAdapter spinnerAdapter = new ArrayAdapter<>(this, R.layout.item_spinner_dropdown, sensorList);
        freq_sp_sensor.setAdapter(spinnerAdapter);
        freq_sp_sensor.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                freq_rb_accx.setChecked(true);
                freq_rb_gj.setChecked(true);
                sensorSelect = sensorList.get(position);
            }

            @Override
            public void onNothingSelected(AdapterView<?> parent) {
            }
        });
        drawGraph(null);
        return true;
    }

    @Override
    protected BasePresenter genPresenter() {
        return null;
    }


    private void showResult() {
        if (freq_et_gd.getText().toString().trim().isEmpty()) {
            ToastUtil.show("请输入结构高度");
            return;
        }
        int imuid = sensorSelect.equals("local") ? -1 : Integer.parseInt(sensorSelect);
        double t0 = getIntent().getDoubleExtra("T0", 0.0),
                t1 = getIntent().getDoubleExtra("T1", 0.0);
        executorService.submit(() -> dataSetManager.calculateFreq(imuid, curAxis, t0, t1,
                Double.parseDouble(freq_et_gd.getText().toString().trim()), curStru,
                FreqDampingActivity.this));
    }


    public double[] convertStringToDoubleArray(String str) {
        str = str.substring(1, str.length() - 1);
        String[] stringValues = str.split(",\\s*");
        double[] doubleArray = new double[stringValues.length];
        for (int i = 0; i < stringValues.length; i++) {
            if(stringValues[i].equals("NaN")) doubleArray[i] = 0.0;
            else doubleArray[i] = Double.parseDouble(stringValues[i]) / 1024;
        }
        return doubleArray;
    }


    private void drawGraph(double[] line) {
        runOnUiThread(() -> {
            mSeries1.setThickness(3);
            mSeries1.setColor(Color.BLUE);
            freq_gv_data.setBackgroundColor(Color.WHITE);
            freq_gv_data.getGridLabelRenderer().setHorizontalAxisTitleTextSize(24);
            freq_gv_data.getGridLabelRenderer().setVerticalAxisTitleTextSize(24);
            freq_gv_data.addSeries(mSeries1);
            freq_gv_data.getViewport().setScrollable(true);
            freq_gv_data.getViewport().setScalable(true);
            freq_gv_data.getViewport().setMinX(0.0f);
            freq_gv_data.getGridLabelRenderer().setHorizontalAxisTitle("频率(Hz)");
            freq_gv_data.getGridLabelRenderer().setVerticalAxisTitle("幅值(m/s^2)");

            initGraphView(line);
        });
    }

    // private void initGraphView(double[] line) {
    //     synchronized (this) {
    //         runOnUiThread(() -> {
    //             if(line == null) return;
    //             mSeries1.resetData(new DataPoint[]{});
    //             double miny = Double.MAX_VALUE, maxy = Double.MIN_VALUE;
    //             for (int i = 0; i < line.length; i++) {
    //                 mSeries1.appendData(new DataPoint(0.01 * i, line[i]), true, Integer.MAX_VALUE);
    //                 miny = Math.min(miny, line[i]);
    //                 maxy = Math.max(maxy, line[i]);
    //             }
    //             freq_gv_data.getViewport().setMaxX(line.length * 0.01);
    //             freq_gv_data.getViewport().setMinX(0);
    //             freq_gv_data.getViewport().setMaxY(maxy);
    //             freq_gv_data.getViewport().setMinY(miny);
    //         });
    //     }
    // }

    private volatile boolean isUpdatingGraph = false;
    private final Object graphLock = new Object();

    private void initGraphView(double[] line) {
        if (line == null || isUpdatingGraph) return;
        try {
            isUpdatingGraph = true;
            runOnUiThread(() -> {
                try {
                    synchronized (graphLock) {
                        if (freq_gv_data == null || isFinishing()) return;
                        DataPoint[] points = new DataPoint[line.length];
                        double miny = Double.MAX_VALUE;
                        double maxy = Double.MIN_VALUE;
                        for (int i = 0; i < line.length; i++) {
                            double x = 0.048828125 * i;
                            double y = line[i];
                            points[i] = new DataPoint(x, y);
                            miny = Math.min(miny, y);
                            maxy = Math.max(maxy, y);
                        }

                        freq_gv_data.removeAllSeries();
                        mSeries1 = new LineGraphSeries<>(points);
                        mSeries1.setThickness(3);
                        mSeries1.setColor(Color.BLUE);

                        freq_gv_data.addSeries(mSeries1);// 更新视图范围

                        double margin = (maxy - miny) * 0.1;
                        freq_gv_data.getViewport().setMinY(miny - margin);
                        freq_gv_data.getViewport().setMaxY(maxy + margin);
                        freq_gv_data.getViewport().setMinX(0);
                        freq_gv_data.getViewport().setMaxX(line.length * 0.01);
                        freq_gv_data.invalidate();// 确保视图更新
                    }
                } catch (Exception e) {
                    LogUtil.e("更新图表失败: " + e.getMessage());
                }
            });
        } finally {
            isUpdatingGraph = false;
        }
    }


    @Override
    public void showLoading() {
        runOnUiThread(() -> {
            loadingDialog = new LoadingDialog(FreqDampingActivity.this);
            loadingDialog.showDialog(FreqDampingActivity.this, "正在计算...", 100);
        });
    }

    @Override
    public void dismissLoading() {
        runOnUiThread(() -> {
            if (loadingDialog != null) loadingDialog.dismiss();
        });
    }

    private final Object uiUpdateLock = new Object();
    @Override
    public void onComplete(ResBean res) {
        runOnUiThread(() -> {
            synchronized (uiUpdateLock) {
                freq_tv_hz.setText(ResBean.getString(res.getA(), "[", "]", 3) + "\n"
                    + ResBean.getString(res.getOri_a(), "(", ")", 3));
                freq_tv_znb.setText(ResBean.getString(res.getB(), "[", "]", 4) + "\n"
                        + ResBean.getString(res.getOri_b(), "(", ")", 4));
                LogUtil.w("c="+res.getC()+"\n");
                if (res.getC() != null)
                    initGraphView(res.getC().stream().mapToDouble(i->i).toArray());
            }
        });
    }

    @Override
    public void onError(String res) {
        runOnUiThread(() -> showErrorDialog(res));
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (freq_gv_data != null) {
            freq_gv_data.removeAllSeries();
            freq_gv_data = null;
        }
        if (executorService != null)
            executorService.shutdown();
    }


    private class FileReadWriteTask extends AsyncTask<Void, Void, Void> {
        private LoadingDialog loadingDialog = null;

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            loadingDialog = new LoadingDialog(FreqDampingActivity.this);
            loadingDialog.showDialog(FreqDampingActivity.this, "正在输出报告...", 5);
        }

        @Override
        protected Void doInBackground(Void... voids) {
            SimpleDateFormat sdf = new SimpleDateFormat();
            sdf.applyPattern("yyyy-MM-dd HH:mm:ss");
            Date date = new Date();

            Map<String, String> replacements = new HashMap<>();
            replacements.put("【时间】", sdf.format(date));
            replacements.put("【姓名】", UserManager.getInstance().getUsername());
            replacements.put("【传感器】", freq_sp_sensor.getSelectedItem().toString().trim());
            replacements.put("【结构高度】", freq_et_gd.getText().toString().trim());
            if(freq_rb_gj.isChecked())
                replacements.put("【结构】", "钢筋混凝土结构");
            else if(freq_rb_gang.isChecked())
                replacements.put("【结构】", "钢结构");
            else
                replacements.put("【结构】", "砌体结构");
            replacements.put("【前三阶频率】", freq_tv_hz.getText().toString().trim());
            replacements.put("【前三阶阻尼比】", freq_tv_znb.getText().toString().trim());
            Bitmap bitmap = PoiUtil.loadBitmapFromView(freq_gv_data);

            synchronized (PoiUtil.class) {
                PoiUtil.replaceFieldsWithImage(bitmap, FreqDampingActivity.this, Constants.METHOD_FREQ,
                        sdf.format(date) + ".docx", replacements);
            }

            return null;
        }

        @Override
        protected void onPostExecute(Void unused) {
            super.onPostExecute(unused);
            if(loadingDialog != null) loadingDialog.dismiss();
            ToastUtil.show("报告已保存");
        }
    }
}